#include <stdio.h>
#define _GNU_SOURCE
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <jansson.h>
#include "config.h" // 包含config.h

// 宏定义用于简洁地处理curl错误
#define CHECK_CURL_RESULT(res) if(res != CURLE_OK) { \
    fprintf(stderr, "curl错误: %s\n", curl_easy_strerror(res)); \
    return NULL; \
}

// 函数声明，用于获取Access Token
char* get_access_token(const char* AK, const char* SK);

// int main() {
//     Config config;
//     if (read_config("app.json", &config) != 0) {
//         fprintf(stderr, "读取配置文件失败\n");
//         return 1;
//     }

//     char* accessToken = get_access_token(config.AK, config.SK);
//     if(accessToken) {
//         printf("Access Token: %s\n", accessToken);
//         free(accessToken); // 使用完毕后释放内存
//     } else {
//         printf("获取Access Token失败。\n");
//     }

//     free_config(&config);
//     return 0;
// }

// 实现获取Access Token的函数
char* get_access_token(const char* AK, const char* SK) {
    CURL *curl; // curl会话句柄
    CURLcode res; // 存储curl操作结果的状态码
    char *post_fields = NULL; // 构造POST请求的参数字符串
    char *access_token = NULL; // 存储获取到的Access Token
    FILE *stream; // 文件流，用于存储curl响应数据
    char *buffer = NULL; // 动态分配的内存缓冲区
    size_t length = 0; // 缓冲区长度

    // 使用asprintf动态构建POST请求参数
    asprintf(&post_fields, "grant_type=client_credentials&client_id=%s&client_secret=%s", AK, SK);

    // 初始化libcurl库
    curl_global_init(CURL_GLOBAL_DEFAULT);
    curl = curl_easy_init();
    if(curl) {
        // 使用open_memstream创建一个内存中的文件流，关联到buffer和length
        stream = open_memstream(&buffer, &length);
        if (!stream) {
            perror("无法打开内存流");
            free(post_fields);
            return NULL;
        }

        // 设置curl选项
        curl_easy_setopt(curl, CURLOPT_URL, "https://aip.baidubce.com/oauth/2.0/token"); // API请求URL
        curl_easy_setopt(curl, CURLOPT_POST, 1L); // 设置请求方法为POST
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_fields); // 设置POST数据
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite); // 设置写入回调函数为fwrite，用于写入内存流
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, stream); // 设置数据写入目标为内存流

        // 执行请求
        res = curl_easy_perform(curl);
        CHECK_CURL_RESULT(res); // 检查curl操作是否成功

        // 关闭内存流
        fclose(stream);

        // 使用jansson解析响应数据
        json_error_t error;
        json_t *root = json_loads(buffer, 0, &error); // 解析JSON
        if (!root) {
            fprintf(stderr, "解析JSON错误: %s\n", error.text);
            free(buffer);
            free(post_fields);
            curl_easy_cleanup(curl);
            curl_global_cleanup();
            return NULL;
        }

        // 从JSON对象中提取access_token
        json_t *token_json = json_object_get(root, "access_token");
        if(!json_is_string(token_json)) {
            fprintf(stderr, "从JSON响应中未能获取到'access_token'\n");
            json_decref(root);
            free(buffer);
            free(post_fields);
            curl_easy_cleanup(curl);
            curl_global_cleanup();
            return NULL;
        }

        // 复制access_token并返回，确保释放原始内存
        access_token = strdup(json_string_value(token_json));
        json_decref(root); // 删除json对象
        free(buffer); // 释放内存缓冲区
        free(post_fields); // 释放POST数据字符串
        curl_easy_cleanup(curl); // 清理curl会话
        curl_global_cleanup(); // 清理全局curl状态
    } else {
        fprintf(stderr, "初始化curl失败\n");
        curl_global_cleanup();
        return NULL;
    }

    return access_token; // 成功获取到的Access Token
}
